package com.kehutong.charge.util;

import com.kehutong.charge.entity.ChargeHouseConfig;
import com.kehutong.charge.util.enums.ResidentsTypeEnum;
import com.kehutong.charge.vo.ArrearsBatchUrgingVO;
import com.kehutong.common.DeptService;
import com.kehutong.common.DoveClient;
import com.kehutong.common.constant.CommonConstant;
import com.kehutong.common.dto.DeptDTO;
import com.kehutong.common.enums.TemplateType;
import com.kehutong.common.errcode.Assert;
import com.kehutong.common.errcode.Result;
import com.kehutong.common.excel.tool.ExcelTool;
import com.kehutong.common.permission.UserLoginInfo;
import com.kehutong.common.util.ConvertUtils;
import com.kehutong.common.util.Token;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.coraframework.authz.Subject;
import org.coraframework.authz.SubjectUtil;
import org.coraframework.bean.Beans;
import org.coraframework.inject.Inject;
import org.coraframework.inject.Singleton;
import org.coraframework.json.JSON;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.orm.Pool;
import org.coraframework.orm.annotation.Transaction;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.util.Objects;
import org.coraframework.util.UUIDGenerator;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @program: kht
 * @description: CommonClient
 * @author: joneron
 * @create: 2021/6/26
 **/
@Singleton
public class CommonClient {

    private static final Logger logger = LoggerFactory.getLogger(CommonClient.class);

    @Inject
    private DoveClient doveClient;

    @Inject
    DeptService deptService;
    @Inject
    ExcelTool excelTool;

    /**
     * 远程调用小区集合数据
     * @return
     * @throws Exception
     */
    public Map<String, JSONObject> getCommunityMap() throws Exception {

        Subject subject = SubjectUtil.getSubject();
        UserLoginInfo userLoginInfo = subject.getAttr(CommonConstant.CURRENT_USER_INFO + ":" + subject.getUserId());
        JSONObject result = doveClient.post("/basic/community/service/permissionList", http -> {
            JSONObject body = new JSONObject();
            body.put("userId",userLoginInfo.getUserId());
            body.put("departmentNo",userLoginInfo.getDepartmentNo());
            body.put("manageDepartmentNo",userLoginInfo.getManageDepartmentNo());
            body.put("identity",userLoginInfo.getIdentity());
            body.put("roles",userLoginInfo.getRoles());
            body.put("allData", userLoginInfo.isAllData());
            http.setBody(body.toString());
        });

        JSONArray data = result.getJSONArray("data");

        if (Objects.isNull(data)) {
            return null;
        }

        Map<String,JSONObject> communityMap = new HashMap<>();
        data.forEach(item->{
            JSONObject obj = (JSONObject) item;
            communityMap.put(obj.getString("id"), obj);
        });

        return communityMap;
    }

    /**
     * 远程调用小区分页
     * @param jsonObject
     * @return
     * @throws Exception
     */
    public JSONArray getHousePage(JSONObject jsonObject) throws Exception{
        JSONObject result = doveClient.post("/basic/house/service/page", http->{
                http.setBody(jsonObject.toJSONString());
        });
        if(result!=null&&result.getIntValue("code")==200) {  //接口调用成功
            JSONArray data = result.getJSONObject("data").getJSONArray("list");
            return data;
        }else{
            return null;
        }
    }


    /**
     * 获取所有房屋
     * @param token
     * @return
     * @throws Exception
     */
    public List<ChargeHouseConfig> getResidentHouseList(Token token) throws Exception {
        List<ChargeHouseConfig> houseList = new ArrayList();
        JSONObject residentResult = doveClient.post("/crm/resident/service/getResidentHouseList", (http) -> {
            http.addHeader("companyNo", token.getCompanyNo());
            JSONObject body = new JSONObject();
            body.put("pageSize", Short.MAX_VALUE);
            body.put("bindType", Arrays.asList("1"));
            http.setBody(body.toJSONString());
        });
        if(!residentResult.getBoolean("isOk")){
            return houseList;
        }
        JSONArray jsonArray = residentResult.getJSONObject("data").getJSONArray("list");
        if(Objects.isEmpty(jsonArray)){
            return houseList;
        }
        for (int i = 0; i < jsonArray.size(); i++) {
            ChargeHouseConfig houseConfig = Pool.newInstance(ChargeHouseConfig.class);
            JSONObject json = jsonArray.getJSONObject(i);
            Beans.from(json).to(houseConfig).igornNull().copy();
            //房屋信息格式化
            ConvertUtils.formatHouseBuildName(houseConfig.getBuildName());
            ConvertUtils.formatHouseUnitName(houseConfig.getUnitName());
            //若需要其他字段请自行添加
            houseList.add(houseConfig);
        }
        return houseList;
    }



    /**
     * 远程调用房屋集合数据(小区下面所有房屋)
     * @return
     * @throws Exception
     */
    public Map<String, JSONObject> getHouseMap(String communityNo) throws Exception {

        JSONArray communityArray = new JSONArray();
        communityArray.add(communityNo);

        JSONObject result = doveClient.post("/basic/house/service/list", http->{
            if(Objects.nonEmpty(communityArray)){
                JSONObject body = new JSONObject();
                body.put("communityNo",communityArray);
                http.setBody(body.toString());
            }
        });

        JSONArray data = result.getJSONArray("data");

        if (Objects.isNull(data)) {
            return null;
        }

        Map<String,JSONObject> houseMap = new HashMap<>();
        data.forEach(item->{
            JSONObject obj = (JSONObject) item;
            houseMap.put(obj.getString("id"), obj);
        });

        return houseMap;
    }

    /**
     * 查房屋信息
     * @param companyNo
     * @param houseNo
     * @return
     * @throws Exception
     */
    public JSONObject getHouseById(String companyNo, String houseNo) throws Exception {
        JSONObject result = doveClient.post("/basic/house/service/get", http->{
            http.addHeader("companyNo", companyNo);
            http.addParam("id", houseNo);
        });

        JSONObject data = result.getJSONObject("data");

        if (Objects.isNull(data)) {
            return null;
        }

        return data;
    }

    public Map<String, JSONObject> getHouseByIdList(String companyNo, List<String> houseNoList) throws Exception {
        JSONObject result = doveClient.post("/basic/house/service/getByIds", http -> {
            http.addHeader("companyNo", companyNo);
            JSONObject body = new JSONObject();
            body.put("id", houseNoList);
            http.setBody(body.toString());
        });

        JSONArray data = result.getJSONArray("data");
        if (Objects.isNull(data)) {
            return null;
        }

        Map<String, JSONObject> houseMap = new HashMap<>();
        data.forEach(item -> {
            JSONObject obj = (JSONObject) item;
            houseMap.put(obj.getString("id"), obj);
        });
        return houseMap;
    }

    /**
     * 远程调用房屋集合数据(楼栋下面所有房屋)
     * @return
     * @throws Exception
     */
    public Map<String, JSONObject> getBuildMap(String buildNo) throws Exception {

        JSONArray buildNoArray = new JSONArray();
        buildNoArray.add(buildNo);

        JSONObject result = doveClient.post("/basic/house/service/list", http->{
            if(Objects.nonEmpty(buildNoArray)){
                JSONObject body = new JSONObject();
                body.put("buildNo",buildNoArray);
                http.setBody(body.toString());
            }
        });

        JSONArray data = result.getJSONArray("data");

        if (Objects.isNull(data)) {
            return null;
        }

        Map<String,JSONObject> houseMap = new HashMap<>();
        data.forEach(item->{
            JSONObject obj = (JSONObject) item;
            houseMap.put(obj.getString("id"), obj);
        });

        return houseMap;
    }


    /**
     * 根据用户id 查询用户信息
     * @param userNo
     * @return
     * @throws Exception
     */
    public JSONObject findResidentInfo(String userNo) throws Exception {

        JSONObject result = doveClient.post("/crm/resident/service/getResidentById", (http) -> {
            JSONObject body = new JSONObject();
            body.put("id",userNo);
            //body.put("mobileValid",true);
            http.setBody(body.toString());
        });

        JSONObject data = result.getJSONObject("data");

        if (Objects.isNull(data)) {
            return null;
        }
        return data;
    }


    /**
     * 添加权限数据
     * @param token
     * @throws Exception
     */
    public T setDepartments(Token token,Class<T> dataEntity) throws Exception {

        List<String> departList = token.getDepartments();
        if(Objects.isEmpty(departList)){
            logger.error("用户{}数据异常，部门为空！",token.getUsername());
        }

        DeptDTO deptDTO = deptService.getDept(departList.get(0));

        return dataEntity.newInstance();
    }

    /**
     * 调用退款接口
     * @param thirdOrderId 订单id
     * @param refundReason 订单说明
     * @throws Exception
     */
    public JSONObject reFundObj(String thirdOrderId,String refundReason) throws Exception {

        //退款调用接口
        JSONObject result = doveClient.post("/payment/wxpay/gateway/service/unified/refund", http->{
            JSONObject body = new JSONObject();
            body.put("thirdOrderId",thirdOrderId);
            body.put("refundReason",refundReason);
            http.setBody(body.toString());
        });

        return result.getJSONObject("data");
    }


    /**
     * 参数：
     *  communityNoSet      小区id列表
     *  communitySet        小区名称列表
     *  buildSet            楼栋名称列表
     *  houseNoSet          房屋id列表
     *  houseNumberSet      楼层房屋号列表
     *  unitNameSet         单元名称列表
     *  chargeNameSet       住户名称列表
     *
     * @param jsonObject
     * @return
     * @throws Exception
     */
    public List<ChargeHouseConfig> getResidentListByMultipleQuery(JSONObject jsonObject) throws Exception {
        JSONObject result = doveClient.post("/basic/house/service/getHouseIdListByMultipleQuery", http->{
            http.setBody(jsonObject.toString());
        });

        JSONArray houseListIds = null;
        if (result.getIntValue("code") == 200) {
            houseListIds = result.getJSONArray("data");
        }
        if (Objects.isEmpty(houseListIds)){
            return new ArrayList<>();
        }
        JSONObject ids = new JSONObject();
        ids.put("ids",houseListIds);

        JSONObject houseResult = doveClient.post("/crm/resident/service/getResidentListByHouseIds", http->{
            http.setBody(ids.toString());
        });
        JSONArray data = houseResult.getJSONArray("data");

        List<ChargeHouseConfig> resultList = new ArrayList();
        for (int i = 0; i < data.size(); i++) {
            ChargeHouseConfig houseConfig = Pool.newInstance(ChargeHouseConfig.class);
            JSONObject json = data.getJSONObject(i);
            Beans.from(json).to(houseConfig).igornNull().copy();

            String mergeName = json.getString("floorName")+json.getString("houseName");
            JSONObject type = json.getJSONObject("type");
            ResidentsTypeEnum reType= null;
            if(!Objects.isEmpty(type)){
                reType = ResidentsTypeEnum.getEnum(type.getString("id"));
            }
            String chargeName = json.getString("realname");
            String ownerNo = json.getString("residentNo");
            houseConfig.setMergeName(mergeName);
            houseConfig.setReType(reType);
            houseConfig.setChargeName(chargeName);
            houseConfig.setOwnerNo(ownerNo);
            //格式统一化
            String buildName = houseConfig.getBuildName();
            if(!Objects.isEmpty(buildName) && !buildName.contains("栋")){
                houseConfig.setBuildName(buildName+"栋");
            }
            String unitName = houseConfig.getUnitName();
            if(!Objects.isEmpty(unitName) && !unitName.contains("单元")){
                houseConfig.setUnitName(unitName+"单元");
            }

            resultList.add(houseConfig);
        }
        return resultList;
    }



    /**
     * 远程调用检查手机号是否存在住户
     */
    public List<Map<String,Object>> getResidentListByMobiles(Set<String> mobileSet) throws Exception {
        JSONObject result = doveClient.post("/crm/resident/service/getResidentListByMobiles", http -> {
            JSONObject body = new JSONObject();
            body.put("mobiles", mobileSet);
            http.setBody(body.toString());
        });
        JSONArray data = result.getJSONArray("data");
        if (Objects.isEmpty(data)) {
            return new ArrayList<>();
        }
        Map<String,Object> item;
        List<Map<String,Object>> list = new ArrayList<>();
        for (int i = 0; i < data.size(); i++) {
            item = new HashMap<>();
            JSONObject json = data.getJSONObject(i);
            String id = json.getString("id");
            item.put("id",id);
            String houseNo = json.getString("houseNo");
            item.put("houseNo",houseNo);
            String avatar = json.getString("avatar");
            item.put("avatar",avatar);
            String mobile = json.getString("mobile");
            item.put("mobile",mobile);
            String realName = json.getString("realname");
            item.put("realName",realName);
            String residentNo = json.getString("residentNo");
            item.put("residentNo",residentNo);
            JSONObject type = json.getJSONObject("type");
            ResidentsTypeEnum reType= null;
            if(!Objects.isEmpty(type)){
                reType = ResidentsTypeEnum.getEnum(type.getString("id"));
            }
            item.put("reType",reType);
            //需要其他字段请自行添加-->Resident.class
            list.add(item);
        }
        return list;
    }


    /**
     * 通过房屋编号批量获取房屋信息
     * @param jsonObject   参数名称为：“ids” 格式为集合
     * @return
     * @throws Exception
     */
    public List<Map<String,Object>> getHouseByIds(JSONObject jsonObject) throws Exception {
        JSONObject result = doveClient.post("/basic/house/service/batch/ids", http -> {
            http.setBody(jsonObject.toString());
        });
        JSONArray data = result.getJSONArray("data");

        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> item;
        for (int i = 0; i < data.size(); i++) {
            JSONObject json = data.getJSONObject(i);
            item = new HashMap<>();
            String id = json.getString("id");
            item.put("id",id);
            String communityNo = json.getString("communityNo");
            item.put("communityNo",communityNo);
            String communityName = json.getString("communityName");
            item.put("communityName",communityName);
            String buildNo = json.getString("buildNo");
            item.put("buildNo",buildNo);
            String buildName = json.getString("buildName");
            item.put("buildName",buildName);
            String unitName = json.getString("unitName");
            item.put("unitName",unitName);
            String floorName = json.getString("floorName");
            item.put("floorName",floorName);
            String houseName = json.getString("name");
            item.put("houseName",houseName);
            String mergeName = json.getString("mergeName");
            item.put("mergeName",mergeName);
            String ownerNo = json.getString("ownerNo");
            item.put("ownerNo",ownerNo);
            String ownerName = json.getString("ownerName");
            item.put("ownerName",ownerName);
            String ownerMobile = json.getString("ownerMobile");
            item.put("ownerMobile",ownerMobile);
            //若需要其他字段后续自行添加
            list.add(item);
        }
        return list;
    }


    public List<Map<String,Object>> getResidentByIds(JSONObject jsonObject) throws Exception {
        JSONObject result = doveClient.post("/crm/resident/service/batch/ids", http -> {
            http.setBody(jsonObject.toString());
        });
        JSONArray data = result.getJSONArray("data");

        List<Map<String,Object>> list = new ArrayList<>();
        Map<String,Object> item;
        for (int i = 0; i < data.size(); i++) {
            JSONObject json = data.getJSONObject(i);
            item = new HashMap<>();
            String id = json.getString("id");
            item.put("id",id);
            String avatar = json.getString("avatar");
            item.put("avatar",avatar);
            //若需要其他字段后续自行添加
            list.add(item);
        }
        return list;
    }


    /**
     * 根据登录ID获取跟进的住户ID
     * @param uuid
     * @return
     */
    public JSONArray getFriendUserNos(String uuid) throws Exception {
        JSONObject result = doveClient.post("/crm/resident/service/getFriendResidentNos", http -> {
            JSONObject body = new JSONObject();
            body.put("uuid", uuid);
            http.setBody(body.toString());
        });
        return result.getJSONArray("data");
    }


    /**
     * 根据登录的管家ID获取管理的房屋ID
     * @param uuid
     * @return
     */
    public JSONArray getStewardHouseNos(String uuid) throws Exception {
        JSONObject result = doveClient.post("/crm/resident/service/getStewardHouseNos", http -> {
            JSONObject body = new JSONObject();
            body.put("uuid", uuid);
            http.setBody(body.toString());
        });
        return result.getJSONArray("data");
    }

    /**
     * 根据登录的管家ID获取管理的房屋ID
     * @param uuid
     * @return
     */
    public JSONArray getStewardCommunity(String uuid) throws Exception {
        JSONObject result = doveClient.post("/crm/resident/service/getStewardCommunity", http -> {
            JSONObject body = new JSONObject();
            body.put("uuid", uuid);
            http.setBody(body.toString());
        });
        return result.getJSONArray("data");
    }


    /**
     * 根据登录ID获取企微外部ID
     * @param uuid
     * @return
     */
    public JSONObject getExternalId(String uuid) throws Exception {
        JSONObject result = doveClient.post("/kht-bin/wwout/getEmployeeByKhtId", http -> {
            JSONObject body = new JSONObject();
            body.put("khtId", uuid);
            http.setBody(body.toJSONString());
        });
        if(Objects.isEmpty(result)){
            return null;
        }
        JSONObject data = result.getJSONObject("data");
        return data;
    }



    /**
     * 通过住户ID批量获取住户信息
     * @param residentIds
     * @return
     * @throws Exception
     */
    public List<ArrearsBatchUrgingVO> batchResidentExternalInfo(JSONArray residentIds) throws Exception {
        JSONObject result = doveClient.post("/crm/resident/service/batchResidentExternalInfo", http -> {
                JSONObject body = new JSONObject();
                body.put("residentIds", residentIds);
                http.setBody(body.toString());
            });

        logger.info("远程调用通过住户ids批量获取住户外部信息返回：{}",result);
        if (Objects.isEmpty(result) || result.getIntValue("code") != 200 || Objects.isEmpty(result.getJSONArray("data"))) {
            return new ArrayList<>();
        }
        JSONArray data = result.getJSONArray("data");
        ArrearsBatchUrgingVO vo;
        List<ArrearsBatchUrgingVO> resultList = new ArrayList<>();
        for (int i = 0; i < data.size(); i++) {
            JSONObject json = data.getJSONObject(i);
            vo = new ArrearsBatchUrgingVO();
            Beans.from(json).to(vo).igornNull().copy();
            resultList.add(vo);
        }
        return resultList;
    }


    /**
     * 获取消息模板
     * @param jsonObject
     * @return
     * @throws Exception
     */
    public JSONObject getTemplateByType(JSONObject jsonObject) throws Exception {
        JSONObject result = doveClient.post("/wechat/template/setting/service/find/msg/template", http -> {
                http.setBody(jsonObject.toString());
            });

        if (result.getIntValue("code") != 200) {
            return null;
        }
        return result.getJSONObject("data");
    }


    /**
     * 刷新企微封面图片
     * @param fileId
     * @return
     * @throws Exception
     */
    public String uploadImage2Material(String fileId,long size) throws Exception {
        JSONObject type = new JSONObject();
        type.put("id","4");

        JSONObject param = new JSONObject();
        param.put("descrition","小程序群发封面");
        param.put("fileId",fileId);
        param.put("fileType","jpg");
        param.put("isFolder",false);
        param.put("memory",size);
        param.put("name","小程序群发封面");
        param.put("type",type);
        param.put("pid", UUIDGenerator.randomUUID());
        param.put("welcome",false);

        JSONObject result = doveClient.post("/crm/material/service/save", http -> {
            http.setBody(param.toString());
        });
        Boolean isOk = result.getBoolean("isOk");
        Assert.mustTrue(isOk,"企微生成素材封面失败，请联系管理员");
        return result.getJSONObject("data").getString("id");
    }



    /**
     * 刷新企微封面图片
     * @param token
     * @param imagesId
     * @return
     * @throws Exception
     */
    public JSONObject refreshMediaId(Token token,String imagesId) throws Exception {
        JSONObject param = new JSONObject();
        param.put("token", token);
        param.put("id",imagesId);

        JSONObject result = doveClient.post("/crm/material/service/byId", http -> {
            http.setBody(param.toString());
        });
        Assert.mustTrue(result.getBoolean("isOk"),"刷新获取MediaId失败");
        JSONObject data = result.getJSONObject("data");
        return data;
    }


    /**
     * 企微发送群发消息
     * @param jsonObject
     * @throws Exception
     */
    public void sendEntWechatMsg2MiniProgram(JSONObject jsonObject) throws Exception {
        JSONObject result = doveClient.post("/kht-bin/wwout/ent/wechat/send/msg/to/mini/program", http -> {
            http.setBody(jsonObject.toString());
        });
        Boolean isOk = result.getBoolean("isOk");
        Assert.mustTrue(isOk,result.getString("message"));
    }

}
